package com.chis.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.ConnectException;
import java.net.URL;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;

import com.chis.bean.EpAccessTokenBean;
import com.chis.bean.EpDepartmentBean;
import com.chis.bean.EpMemberBean;
import com.chis.bean.EpMenuBean;
import com.chis.bean.EpSendMsgBean;
import com.chis.bean.MyX509TrustManager;

/**
 * 
 * @Title:EpWxUtil
 * @Description:微信企业号公共类
 * @Company:zwx
 * @author:jw
 * @date:2016年10月25日
 */
public class EpWxUtil implements Serializable {

	private static final long serialVersionUID = 1L;

	/** 管理组账号 */
	private final static String CorpID = "wxde61f368e7778165";

	/** 管理组密码 */
	private final static String Secret = "JWKxerx2dnnzU8YdKXjJMX2RWok95BiFl2h6WQwy6_cHQeHuna5jLN7aiyZXLpgW";

	/** token获取地址 */
	private final static String ep_gettoken_url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=myCorpid&corpsecret=myCorpsecret";

	/** 菜单创建地址 */
	private final static String ep_menu_create_url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?access_token=myAccessToken&agentid=myAgentid";

	/** 菜单删除地址 */
	private final static String ep_menu_delete_url = "https://qyapi.weixin.qq.com/cgi-bin/menu/delete?access_token=myAccessToken&agentid=myAgentid";

	/** 获取部门列表地址 */
	public final static String ep_department_list_url = "https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=myAccessToken&id=myId";

	/** 主动发送消息地址 */
	public final static String ep_message_send_url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=myAccessToken";

	/** 成员创建地址 */
	public final static String ep_user_create_url = "https://qyapi.weixin.qq.com/cgi-bin/user/create?access_token=myAccessToken";

	/** 获取部门成员地址 */
	public final static String ep_user_simplelist_url = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token=myAccessToken&department_id=myDepartmentId&fetch_child=myFetchChild&status=myStatus";

	/** 获取部门成员(详情)地址 */
	public final static String ep_user_list_url = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=myAccessToken&department_id=myDepartmentId&fetch_child=myFetchChild&status=myStatus";

	/**
	 * 获取token
	 * 
	 * @return
	 * @throws Exception
	 */
	public static EpAccessTokenBean selecToken(String epCode) throws Exception {
		EpAccessTokenBean accessToken = null;
		try {
			Properties p = new Properties();
			String path = "/weblogic/token/eptoken.properties";
			File f = new File(path);
			p.load(new FileInputStream(f));
			Object tokenPro = p.get(epCode);
			if (tokenPro != null) {
				String tokenValue = tokenPro.toString().split("#")[0];
				long time = Long.parseLong(tokenPro.toString().split("#")[1]);
				long nowTime = new Date().getTime() / 1000l;
				// 如果token未过期
				if (time >= nowTime) {
					accessToken = new EpAccessTokenBean();
					accessToken.setToken(tokenValue);
				}
			}
		} catch (Exception e) {
			accessToken = null;
			e.printStackTrace();
		}
		return accessToken;
	}
	
	public static void main(String[] args) {
		EpAccessTokenBean accessToken = null;
		try {
			Properties p = new Properties();
			String path = "/weblogic/token/eptoken.properties";
			File f = new File(path);
			String requestUrl = ep_gettoken_url.replace("myCorpid", CorpID).replace("myCorpsecret", Secret);
			System.out.println("requestUrl:"+requestUrl);
			JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
			System.out.println("jsonObject:"+jsonObject);
			accessToken = new EpAccessTokenBean();
			accessToken.setToken(jsonObject.getString("access_token"));
			FileOutputStream fos = new FileOutputStream(f);
			long nowTime = new Date().getTime() / 1000l;
			p.setProperty("eptoken", accessToken.getToken() + "#" + (nowTime + 6000));
			p.store(fos, null);
			fos.flush();
			fos.close();
		} catch (Exception e) {
			accessToken = null;
			e.printStackTrace();
		}
	}

	/**
	 * 设置token
	 * 
	 * @return
	 * @throws Exception
	 */
	public static EpAccessTokenBean createToken(String epCode) throws Exception {
		EpAccessTokenBean accessToken = null;
		try {
			Properties p = new Properties();
			String path = "/weblogic/token/eptoken.properties";
			File f = new File(path);
			String requestUrl = ep_gettoken_url.replace("myCorpid", CorpID).replace("myCorpsecret", Secret);
			JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
			accessToken = new EpAccessTokenBean();
			accessToken.setToken(jsonObject.getString("access_token"));
			FileOutputStream fos = new FileOutputStream(f);
			long nowTime = new Date().getTime() / 1000l;
			p.setProperty(epCode, accessToken.getToken() + "#" + (nowTime + 6000));
			p.store(fos, null);
			fos.flush();
			fos.close();
		} catch (Exception e) {
			accessToken = null;
			e.printStackTrace();
		}
		return accessToken;
	}

	/**
	 * 创建菜单
	 * 
	 * @param accessToken
	 * @param bean
	 *            必须。菜单对象
	 * @param agentid
	 *            必须。应用ID
	 * @return
	 */
	public static int createMenu(String accessToken, EpMenuBean bean, String agentid) {
		int result = 0;
		String url = ep_menu_create_url.replace("myAccessToken", accessToken).replace("myAgentid", agentid);
		String jsonMenu = JSONObject.fromObject(bean).toString();
		JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);
		if (null != jsonObject) {
			if (0 != jsonObject.getInt("errcode")) {
				result = jsonObject.getInt("errcode");
				System.out.println("创建菜单失败 errcode:{} errmsg:{}" + jsonObject.getInt("errcode") + ":" + jsonObject.getString("errmsg"));
			}
		} else {
			System.out.println("创建菜单失败!");
		}
		return result;
	}

	/**
	 * 删除菜单
	 * 
	 * @param accessToken
	 * @param agentid
	 *            必须。应用ID
	 * @return
	 */
	public static int deleteMenu(String accessToken, String agentid) {
		int result = 0;
		String url = ep_menu_delete_url.replace("myAccessToken", accessToken).replace("myAgentid", agentid);
		JSONObject jsonObject = httpRequest(url, "GET", null);
		if (null != jsonObject) {
			if (0 != jsonObject.getInt("errcode")) {
				result = jsonObject.getInt("errcode");
				System.out.println("删除菜单失败 errcode:{} errmsg:{}" + jsonObject.getInt("errcode") + ":" + jsonObject.getString("errmsg"));
			}
		} else {
			System.out.println("删除菜单失败!");
		}
		return result;
	}

	/**
	 * 获取部门列表
	 * 
	 * @param accessToken
	 * @param id
	 *            非必须。部门id。获取指定部门及其下的子部门
	 * @return
	 */
	public static List<EpDepartmentBean> listDepartment(String accessToken, String id) {
		List<EpDepartmentBean> list = new LinkedList<>();
		String url = ep_department_list_url.replace("myAccessToken", accessToken).replace("myId", id);
		JSONObject jsonObject = httpRequest(url, "GET", null);
		if (null != jsonObject) {
			try {
				JSONArray jsonArray = JSONArray.fromObject(jsonObject.get("department"));
				list = (List<EpDepartmentBean>) JSONArray.toCollection(jsonArray, EpDepartmentBean.class);
			} catch (Exception e) {
				// 获取token失败
				System.out.println("获取部门失败 errcode:{} errmsg:{}" + jsonObject.getInt("errcode") + ":" + jsonObject.getString("errmsg"));
			}
		} else {
			System.out.println("获取部门失败!");
		}
		return list;
	}

	/**
	 * 主动发送消息
	 * 
	 * @param accessToken
	 * @param bean
	 *            消息对象
	 * @return
	 * @throws Exception
	 */
	public static int sendMessage(String accessToken, EpSendMsgBean bean) throws Exception {
		int result = 0;
		String url = ep_message_send_url.replace("myAccessToken", accessToken);
		String jsonBm = JSONObject.fromObject(bean).toString();
		JSONObject jsonObject = httpRequest(url, "POST", jsonBm);
		if (null != jsonObject) {
			if (0 != jsonObject.getInt("errcode")) {
				result = jsonObject.getInt("errcode");
				System.out.println(bean.getTouser() + ":发送客服消息失败 errcode:{} errmsg:{}" + jsonObject.getInt("errcode") + ":"
						+ jsonObject.getString("errmsg"));
				return jsonObject.getInt("errcode");
			}
		} else {
			System.out.println("发送客服消息失败!");
			throw new Exception("发送客服消息失败!");
		}
		return result;
	}

	/**
	 * 成员创建
	 * 
	 * @param accessToken
	 * @param bean
	 *            成员对象
	 * @return
	 */
	public static int createUser(String accessToken, EpMemberBean bean) {
		int result = 0;
		String url = ep_user_create_url.replace("myAccessToken", accessToken);
		String postJson = "{\"userid\":\"%s\",\"name\":\"%s\",\"department\":[\"%s\"],\"position\": \"%s\",\"mobile\": \"%s\",\"gender\": \"%s\",\"email\":\"%s\",\"weixinid\":\"%s\"}";
		String outputStr = String.format(postJson, bean.getUserid(), bean.getName(), StringUtils.join(bean.getDepartment(), ","),
				bean.getPosition() != null ? bean.getPosition() : "", bean.getMobile() != null ? bean.getMobile() : "",
				bean.getGender() != null ? bean.getGender() : "", bean.getEmail() != null ? bean.getEmail() : "",
				bean.getWeixinid() != null ? bean.getWeixinid() : "");
		JSONObject jsonObject = httpRequest(url, "POST", outputStr);
		if (null != jsonObject) {
			if (0 != jsonObject.getInt("errcode")) {
				result = jsonObject.getInt("errcode");
				System.out.println("创建成员失败 errcode:{} errmsg:{}" + jsonObject.getInt("errcode") + ":" + jsonObject.getString("errmsg"));
			}
		} else {
			System.out.println("创建成员失败!");
		}
		return result;
	}

	/**
	 * 获取部门成员
	 * 
	 * @param accessToken
	 * @param departmentId
	 *            获取的部门id
	 * @param fetchChild
	 *            1/0：是否递归获取子部门下面的成员
	 * @param status
	 *            0获取全部成员，1获取已关注成员列表，2获取禁用成员列表，4获取未关注成员列表。status可叠加，未填写则默认为4
	 * @return
	 */
	public static List<EpMemberBean> simplelistUser(String accessToken, String departmentId, String fetchChild, String status) {
		List<EpMemberBean> list = new LinkedList<>();
		String url = ep_user_simplelist_url.replace("myAccessToken", accessToken).replace("myDepartmentId", departmentId)
				.replace("myFetchChild", fetchChild).replace("myStatus", status);
		JSONObject jsonObject = httpRequest(url, "GET", null);
		if (null != jsonObject) {
			try {
				if (0 != jsonObject.getInt("errcode")) {
					System.out.println("获取成员失败 errcode:{} errmsg:{}" + jsonObject.getInt("errcode") + ":" + jsonObject.getString("errmsg"));
				} else {
					JSONArray jsonArray = JSONArray.fromObject(jsonObject.get("userlist"));
					list = (List<EpMemberBean>) JSONArray.toCollection(jsonArray, EpMemberBean.class);
				}
			} catch (Exception e) {
				// 获取token失败
				System.out.println("获取成员失败 errcode:{} errmsg:{}" + jsonObject.getInt("errcode") + ":" + jsonObject.getString("errmsg"));
			}
		} else {
			System.out.println("获取成员失败!");
		}
		return list;
	}

	/**
	 * 获取部门成员(详情)
	 * 
	 * @param accessToken
	 * @param departmentId
	 *            获取的部门id
	 * @param fetchChild
	 *            1/0：是否递归获取子部门下面的成员
	 * @param status
	 *            0获取全部成员，1获取已关注成员列表，2获取禁用成员列表，4获取未关注成员列表。status可叠加，未填写则默认为4
	 * @return
	 */
	public static List<EpMemberBean> listUser(String accessToken, String departmentId, String fetchChild, String status) {
		List<EpMemberBean> list = new LinkedList<>();
		String url = ep_user_list_url.replace("myAccessToken", accessToken).replace("myDepartmentId", departmentId)
				.replace("myFetchChild", fetchChild).replace("myStatus", status);
		JSONObject jsonObject = httpRequest(url, "GET", null);
		if (null != jsonObject) {
			try {
				if (0 != jsonObject.getInt("errcode")) {
					System.out.println("获取成员失败 errcode:{} errmsg:{}" + jsonObject.getInt("errcode") + ":" + jsonObject.getString("errmsg"));
				} else {
					JSONArray jsonArray = JSONArray.fromObject(jsonObject.get("userlist"));
					list = (List<EpMemberBean>) JSONArray.toCollection(jsonArray, EpMemberBean.class);
				}
			} catch (Exception e) {
				// 获取token失败
				System.out.println("获取成员失败 errcode:{} errmsg:{}" + jsonObject.getInt("errcode") + ":" + jsonObject.getString("errmsg"));
			}
		} else {
			System.out.println("获取成员失败!");
		}
		return list;
	}

	/**
	 * url请求
	 * 
	 * @param requestUrl
	 *            地址
	 * @param requestMethod
	 *            http请求方式
	 * @param outputStr
	 *            数据
	 * @return
	 */
	private static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();
			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);
			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);
			if ("GET".equalsIgnoreCase(requestMethod))
				httpUrlConn.connect();
			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}
			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
			jsonObject = JSONObject.fromObject(buffer.toString());
		} catch (ConnectException ce) {
			System.out.println("Weixin server connection timed out.");
		} catch (Exception e) {
			System.out.println("https request error:{}");
		}
		return jsonObject;
	}
}
